package com.graduation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.graduation.common.exceptions.BizException;
import com.graduation.mapper.CategoryMapper;
import com.graduation.pojo.po.Category;
import com.graduation.pojo.query.CategoryQuery;
import com.graduation.pojo.vo.CategoryVO;
import com.graduation.service.CategoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Override
    public List<CategoryVO> listCategories(CategoryQuery query) {
        // 构建查询条件
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(query.getParentId() != null, Category::getParentId, query.getParentId())
                .like(StrUtil.isNotBlank(query.getName()), Category::getName, query.getName())
                .eq(query.getLevel() != null, Category::getLevel, query.getLevel())
                .orderByAsc(Category::getLevel)
                .orderByDesc(Category::getCreateTime);

        // 查询并转换为VO
        List<Category> categories = list(wrapper);
        return categories.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public CategoryVO getCategoryById(Long id) {
        Category category = getById(id);
        if (category == null) {
            throw new BizException("分类不存在");
        }
        return convertToVO(category);
    }

    @Override
    public void saveCategory(Category category) {
        // 检查分类名称是否已存在（同一父级下）
        boolean exists = lambdaQuery()
                .eq(Category::getName, category.getName())
                .eq(Category::getParentId, category.getParentId())
                .exists();
        if (exists) {
            throw new BizException("同级分类名称已存在");
        }

        // 如果有父分类，验证父分类是否存在并设置层级
        if (category.getParentId() != null && category.getParentId() > 0) {
            Category parent = getById(category.getParentId());
            if (parent == null) {
                throw new BizException("父分类不存在");
            }
            category.setLevel(parent.getLevel() + 1);
        } else {
            // 顶级分类
            category.setParentId(0L);
            category.setLevel(1);
        }

        save(category);
    }

    @Override
    public void updateCategory(Category category) {
        Category existCategory = getById(category.getId());
        if (existCategory == null) {
            throw new BizException("分类不存在");
        }

        // 检查分类名称是否被其他分类使用（同一父级下）
        if (StrUtil.isNotBlank(category.getName()) && 
            !category.getName().equals(existCategory.getName())) {
            boolean exists = lambdaQuery()
                    .eq(Category::getName, category.getName())
                    .eq(Category::getParentId, 
                        category.getParentId() != null ? category.getParentId() : existCategory.getParentId())
                    .ne(Category::getId, category.getId())
                    .exists();
            if (exists) {
                throw new BizException("同级分类名称已存在");
            }
        }

        // 如果修改了父分类，需要重新计算层级
        if (category.getParentId() != null && 
            !category.getParentId().equals(existCategory.getParentId())) {
            if (category.getParentId() > 0) {
                Category parent = getById(category.getParentId());
                if (parent == null) {
                    throw new BizException("父分类不存在");
                }
                // 检查是否会造成循环引用
                if (isCircularReference(category.getId(), category.getParentId())) {
                    throw new BizException("不能将分类移动到自己的子分类下");
                }
                category.setLevel(parent.getLevel() + 1);
            } else {
                category.setParentId(0L);
                category.setLevel(1);
            }
        }

        updateById(category);
    }

    @Override
    public void deleteCategory(Long id) {
        Category category = getById(id);
        if (category == null) {
            throw new BizException("分类不存在");
        }

        // 检查是否有子分类
        boolean hasChildren = lambdaQuery()
                .eq(Category::getParentId, id)
                .exists();
        if (hasChildren) {
            throw new BizException("该分类下存在子分类，无法删除");
        }

        // TODO: 检查是否有关联的法律条款
        // boolean hasLaws = lawService.lambdaQuery()
        //         .eq(Law::getCategoryId, id)
        //         .exists();
        // if (hasLaws) {
        //     throw new BizException("该分类下存在法律条款，无法删除");
        // }

        removeById(id);
    }

    /**
     * 检查是否会造成循环引用
     */
    private boolean isCircularReference(Long categoryId, Long parentId) {
        if (parentId == null || parentId <= 0) {
            return false;
        }
        if (categoryId.equals(parentId)) {
            return true;
        }
        Category parent = getById(parentId);
        if (parent == null) {
            return false;
        }
        return isCircularReference(categoryId, parent.getParentId());
    }

    /**
     * 转换为VO对象
     */
    private CategoryVO convertToVO(Category category) {
        CategoryVO vo = new CategoryVO();
        BeanUtil.copyProperties(category, vo);
        return vo;
    }
}
